﻿#region Using Directives

using System;
using System.IO;
using System.Windows.Forms;
using System.Globalization;
using Microsoft.Practices.ComponentModel;
using Microsoft.Practices.RecipeFramework;
using Microsoft.Practices.RecipeFramework.Library;
using Microsoft.Practices.RecipeFramework.Services;
using Microsoft.Practices.RecipeFramework.VisualStudio;
using Microsoft.Practices.RecipeFramework.VisualStudio.Templates;
using EnvDTE;
using System.Xml;
using System.Collections.Specialized;

#endregion

namespace SteriaMummert.SharePoint.SoftwareFactoryLite.Actions
{
    /// <summary>
    /// </summary>
    [ServiceDependency(typeof(DTE))]
    public class CreateApplicationDiagram : ConfigurableAction
    {
        private StringCollection internalFeatures = new StringCollection();

        private string GetApplicationDiagramFile(DTE dte)
        {
            //Path to the solution directory
            string solutionDirectory = Path.GetDirectoryName((string)dte.Solution.Properties.Item("Path").Value);
            string toPath = Path.Combine(solutionDirectory, "ApplicationDiagram.spl");

            return toPath;
        }

        private string GetApplicationDiagramDiagramFile(DTE dte)
        {
            //Path to the solution directory
            string solutionDirectory = Path.GetDirectoryName((string)dte.Solution.Properties.Item("Path").Value);
            string toPath = Path.Combine(solutionDirectory, "ApplicationDiagram.spl.diagram");

            return toPath;
        }

        private string GetID()
        {
            return Guid.NewGuid().ToString().Replace("{", "").Replace("}", "");
        }

        private void LoadInternalFeatures(EnvDTE.DTE vs)
        {
            foreach (Project p in vs.Solution.Projects)
            {
                LoadInternalFeatures(p.ProjectItems);
            }
        }

        private void LoadInternalFeatures(ProjectItems projectItems)
        {
            if (projectItems != null)
            {
                foreach (ProjectItem pitem in projectItems)
                {

                    if (pitem.Name.ToUpper() == "FEATURE.XML")
                    {
                        try
                        {
                            string filepath = pitem.Properties.Item("FullPath").Value.ToString();
                            XmlDocument featuredoc = new XmlDocument();
                            featuredoc.Load(filepath);

                            XmlNamespaceManager mgr = new XmlNamespaceManager(featuredoc.NameTable);
                            mgr.AddNamespace("ns", "http://schemas.microsoft.com/sharepoint/");

                            XmlNode featurenode = featuredoc.SelectSingleNode("/ns:Feature", mgr);
                            if (featurenode != null)
                            {
                                if (featurenode.Attributes["Id"] != null)
                                {
                                    internalFeatures.Add(featurenode.Attributes["Id"].Value);
                                }
                            }
                        }
                        catch (Exception ex)
                        {

                        }
                    }
                    LoadInternalFeatures(pitem.ProjectItems);
                }
            }
        }

        public override void Execute()
        {
            EnvDTE.DTE vs = this.GetService<EnvDTE.DTE>(true);

            LoadInternalFeatures(vs);

            
            string filePath = GetApplicationDiagramFile(vs);
            string filePathDiagram = GetApplicationDiagramDiagramFile(vs);

            XmlWriterSettings wSettings = new XmlWriterSettings();
            wSettings.Indent = true;
            
            //diagramfile löschen
            if (File.Exists(filePathDiagram))
            {
                File.Delete(filePathDiagram);
            }
            
            FileStream ms = null;
            if (File.Exists(filePath))
            {
                ms = new FileStream(filePath, FileMode.Truncate);
            }
            else
            {
                ms = new FileStream(filePath, FileMode.CreateNew);
            }

            try
            {

            XmlWriter xw = XmlWriter.Create(ms, wSettings);
            xw.WriteStartDocument();

            
            xw.WriteStartElement("mOSSApplicationModel","http://schemas.microsoft.com/dsltools/SPALMApplicationLanguage");
            xw.WriteStartAttribute("Id");
            xw.WriteString(GetID());
            xw.WriteStartAttribute("dslVersion");
            xw.WriteString("1.0.0.0");

                xw.WriteStartElement("mOSSApplications");

                    xw.WriteStartElement("mOSSApplication");
                    xw.WriteStartAttribute("Id");
                    xw.WriteString(GetID());
                    xw.WriteStartAttribute("name");
                    xw.WriteString(vs.Solution.Properties.Item("Name").Value.ToString());

                        xw.WriteStartElement("wSPSolutions");

                        foreach (Project p in vs.Solution.Projects)
                        {
                            if (p.Name != "Solution Items")
                            {

                                xw.WriteStartElement("wSPSolution");
                                xw.WriteStartAttribute("name");
                                xw.WriteString(p.Name);

                                xw.WriteStartElement("features");

                                AddFeatures(p.ProjectItems, xw);

                                //features
                                xw.WriteEndElement();

                                //wSPSolution
                                xw.WriteEndElement();
                            }
                        }

                        //wSPSolutions
                        xw.WriteEndElement();

                    //mOSSApplication
                    xw.WriteEndElement();

                //mOSSApplications
                xw.WriteEndElement();

            //mOSSApplicationModel
            xw.WriteEndElement();

            xw.Flush();
            xw.Close();

           
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            ms.Close();
        }

        private void AddFeatures(ProjectItems projectItems, XmlWriter xw)
        {
           
            foreach (ProjectItem pitem in projectItems)
            {
                
                if (pitem.Name.ToUpper() == "FEATURE.XML")
                {
                    try
                    {
                        xw.WriteStartElement("feature");

                        string filepath = pitem.Properties.Item("FullPath").Value.ToString();
                        XmlDocument featuredoc = new XmlDocument();
                        featuredoc.Load(filepath);

                        XmlNamespaceManager mgr = new XmlNamespaceManager(featuredoc.NameTable);
                        mgr.AddNamespace("ns", "http://schemas.microsoft.com/sharepoint/");

                        XmlNode featurenode = featuredoc.SelectSingleNode("/ns:Feature", mgr);
                        if (featurenode != null)
                        {
                            //Id=
                            if (featurenode.Attributes["Id"] != null)
                            {
                                xw.WriteStartAttribute("Id");
                                xw.WriteString(featurenode.Attributes["Id"].Value);
                            }

                            if (featurenode.Attributes["Title"] != null)
                            {
                                xw.WriteStartAttribute("name");
                                xw.WriteString(featurenode.Attributes["Title"].Value);
                            }

                            if (featurenode.Attributes["Description"] != null)
                            {
                                xw.WriteStartAttribute("description");
                                xw.WriteString(featurenode.Attributes["Description"].Value);
                            }
                        }

                        
                        foreach(XmlNode activation in featuredoc.SelectNodes("/ns:Feature/ns:ActivationDependencies/ns:ActivationDependency", mgr))
                        {
                            if (activation.Attributes["FeatureId"] != null)
                            {
                                //ist es ein internes feature??
                                if(internalFeatures.Contains(activation.Attributes["FeatureId"].Value))
                                {
                                    xw.WriteStartElement("ActivationDependency");

                                     xw.WriteStartAttribute("Id");
                                     xw.WriteString(activation.Attributes["FeatureId"].Value);

                                    //ActivationDependency
                                    xw.WriteEndElement();
                                }
                             }
                        }

                        //feature
                        xw.WriteEndElement();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
                }

                AddFeatures(pitem.ProjectItems, xw);
            }
        }

        public override void Undo()
        {
        }
    }
}